/*
 * FileSystemPanel.java
 *
 * Created on December 3, 2006, 10:56 PM
 */

package eu.somatik.somaftp.gui;

import eu.somatik.somaftp.gui.dnd.FileTransferHandler;
import eu.somatik.somaftp.logic.FileInterface;
import eu.somatik.somaftp.logic.FileSystemException;
import eu.somatik.somaftp.logic.FileSystemInterface;
import eu.somatik.somaftp.logic.FileSystemListener;
import eu.somatik.somaftp.gui.logic.FileSystemTableModel;
import eu.somatik.somaftp.logic.ftp.FTPFileSystem;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.JOptionPane;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

/**
 *
 * @author  francisdb
 */
public class FileSystemPanel extends javax.swing.JPanel {
    
    private FileSystemInterface fileSystem;
    
    private MainFrame mainFrame;
    
    private final FileSystemTableModel model;
    
    private final HourGlass glass;
    
    /** Creates new form FileSystemPanel */
    public FileSystemPanel() {
        initComponents();
        this.model = new FileSystemTableModel();
        fileTable.setAutoCreateRowSorter(true);
        fileTable.setFillsViewportHeight(true);
        fileTable.setModel(model);
//        TableRowSorter<FileSystemTableModel> sorter = new TableRowSorter<FileSystemTableModel>(model);
//        fileTable.setRowSorter(sorter);
        List<RowSorter.SortKey> keys = new ArrayList<RowSorter.SortKey>();
        keys.add(new RowSorter.SortKey(0, SortOrder.ASCENDING));
        fileTable.getRowSorter().setSortKeys(keys);
        fileTable.setDefaultRenderer(FileInterface.class, new FileListCellRenderer());
        fileTable.setTransferHandler(new FileTransferHandler());
        glass = new HourGlass(loadingLabel);
    }

    
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {

        pathComboBox.setEditable(true);
        pathComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pathComboBoxActionPerformed(evt);
            }
        });

        toolBar.setFloatable(false);
        connectButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/eu/somatik/somaftp/icons/network-wired.png")));
        connectButton.setToolTipText("Connect");
        connectButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                connectButtonActionPerformed(evt);
            }
        });

        toolBar.add(connectButton);

        disconnectButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/eu/somatik/somaftp/icons/network-offline.png")));
        disconnectButton.setToolTipText("Disconnect");
        disconnectButton.setEnabled(false);
        disconnectButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                disconnectButtonActionPerformed(evt);
            }
        });

        toolBar.add(disconnectButton);

        refreshButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/eu/somatik/somaftp/icons/view-refresh.png")));
        refreshButton.setToolTipText("Refresh");
        refreshButton.setEnabled(false);
        refreshButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                refreshButtonActionPerformed(evt);
            }
        });

        toolBar.add(refreshButton);

        fileTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {},
                {},
                {}
            },
            new String [] {

            }
        ));
        fileTable.setDragEnabled(true);
        fileTable.setIntercellSpacing(new java.awt.Dimension(0, 0));
        fileTable.setShowHorizontalLines(false);
        fileTable.setShowVerticalLines(false);
        fileTable.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                fileTableKeyPressed(evt);
            }
        });
        fileTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                fileTableMouseClicked(evt);
            }
        });

        fileTableScrollPane.setViewportView(fileTable);

        loadingLabel.setText("/  ");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(toolBar, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(loadingLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pathComboBox, 0, 361, Short.MAX_VALUE))
            .addComponent(fileTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(toolBar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, 0)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(pathComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(loadingLabel))
                .addGap(0, 0, 0)
                .addComponent(fileTableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 232, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents
    
    private void fileTableKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_fileTableKeyPressed
        switch(evt.getKeyCode()){
            case KeyEvent.VK_DELETE:
                int[] selectedRows = fileTable.getSelectedRows();
                Object[] values = new Object[selectedRows.length];
                
                for(int i= 0; i< values.length; i++){
                    values[i] = fileTable.getValueAt(selectedRows[i], 0);
                }
                String message = null;
                if(values.length == 1){
                    message = "Are you sure you want to delete "+values[0]+"?";
                }else{
                    message = "Are you sure you want to delete "+values.length+" objects?";
                }
                int result = JOptionPane.showConfirmDialog(this, message, "Confirm", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
                if(result == JOptionPane.YES_OPTION){
                    try {
                        // TODO recursive delete
                        getFileSystem().delete(values);
                    } catch (FileSystemException ex) {
                        mainFrame.showError(ex);
                    }
                }
                break;
            case KeyEvent.VK_ENTER:
                int row = fileTable.getSelectedRow();
                if(row != -1){
                    getFileSystem().request(fileTable.getValueAt(row, 0));
                    evt.consume();
                }
                break;
            default:
                // do nothing
                
        }
    }//GEN-LAST:event_fileTableKeyPressed
    
    private void fileTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_fileTableMouseClicked
        if(evt.getClickCount() == 2){
            Object file = fileTable.getValueAt(fileTable.getSelectedRow(), 0);
            if(SwingUtilities.isRightMouseButton(evt)){
                getFileSystem().queue(file);
            }else{
                getFileSystem().request(file);
            }
            pathComboBox.setSelectedItem(getFileSystem().getPath());
        }
    }//GEN-LAST:event_fileTableMouseClicked
    
    private void pathComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pathComboBoxActionPerformed
        pathComboBox.getSelectedItem();
        //connection.cd(file);
    }//GEN-LAST:event_pathComboBoxActionPerformed
    
    private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed
        refresh();
    }//GEN-LAST:event_refreshButtonActionPerformed
    
    private void disconnectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_disconnectButtonActionPerformed
        disconnectButton.setEnabled(false);
        refreshButton.setEnabled(false);
        getFileSystem().disconnect();
        model.clear();
        connectButton.setEnabled(true);
    }//GEN-LAST:event_disconnectButtonActionPerformed
    
    private void connectButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_connectButtonActionPerformed
        connect();
    }//GEN-LAST:event_connectButtonActionPerformed
    
    private void connect(){
        glass.start();
        new SwingWorker() {
            protected Object doInBackground() throws Exception {
                getFileSystem().connect(mainFrame.getLogModel());
                return null;
            }
            
            protected void done() {
                try {
                    get();
                    pathComboBox.setSelectedItem(getFileSystem().getPath());
                    if(!fileSystem.isAlwaysConnected()){
                        disconnectButton.setEnabled(true);
                    }
                    connectButton.setEnabled(false);
                    refreshButton.setEnabled(true);
                    refresh();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                } catch (ExecutionException ex) {
                    mainFrame.showError(ex.getCause());
                }
                glass.stop();
            }
            
        }.execute();
    }
    
    
    private void refresh(){
        glass.start();
        new SwingWorker<List<FileInterface>,String>() {
            protected List<FileInterface> doInBackground() throws Exception {
                return getFileSystem().list(true);
            }
            
            protected void done() {
                try {
                    model.setFiles(get());
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                } catch (ExecutionException ex) {
                    mainFrame.showError(ex.getCause());
                }
                glass.stop();
            }
            
        }.execute();
    }
    
    public FileSystemInterface getFileSystem() {
        return fileSystem;
    }
    
    public void setFileSystem(FileSystemInterface fileSystem) {
        this.fileSystem = fileSystem;
        if (fileSystem.isAlwaysConnected()){
            connectButton.setEnabled(false);
            disconnectButton.setEnabled(false);
            connect();
        }
        this.fileSystem.addListener(new FileSystemListener() {
            
            public void update(final List<FileInterface> list, final String path) {
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                       model.setFiles(list);
                       pathComboBox.setSelectedItem(path);
                    }
                });
            }
        });
    }

    public void setMainFrame(MainFrame mainFrame) {
        this.mainFrame = mainFrame;
    }
    
    
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private final javax.swing.JButton connectButton = new javax.swing.JButton();
    private final javax.swing.JButton disconnectButton = new javax.swing.JButton();
    private final javax.swing.JTable fileTable = new javax.swing.JTable();
    private final javax.swing.JScrollPane fileTableScrollPane = new javax.swing.JScrollPane();
    private final javax.swing.JLabel loadingLabel = new javax.swing.JLabel();
    private final javax.swing.JComboBox pathComboBox = new javax.swing.JComboBox();
    private final javax.swing.JButton refreshButton = new javax.swing.JButton();
    private final javax.swing.JToolBar toolBar = new javax.swing.JToolBar();
    // End of variables declaration//GEN-END:variables
    
}
